package com.nf.sms.dao.impl;

import com.nf.sms.dao.BankDao;
import com.nf.sms.utils.DbUtil;

import java.sql.*;

/**
 * @author ZQX
 * @date 2024-10-11
 */
public class BankDaoImpl implements BankDao {
    @Override
    public int updateMoney(String outUser, String inUser, double money) {
        int r = 0;

        // 第一：定义要操作数据库的 SQL 语句，参数使用 ? 占位符代替
        String outSql = "update bank set currentMoney = currentMoney - ? where customerName = ?";
        String inSql = "update bank set currentMoney = currentMoney + ? where customerName = ?";

        // 第二：获取连接对象
        Connection conn = DbUtil.getConnection();

        try {
            conn.setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        PreparedStatement psmt1 = null ;
        PreparedStatement psmt2 = null ;


        // ------------ 转出操作 ----------------
        try {
            // 第三：预编译 SQL 语句 - 获取语句对象
            psmt1 = conn.prepareStatement(outSql);

            // 第四：给占位符填充数据 - 注：Xxx代表是数据类型
            // 语句对象.setXxx(参数索引,值)
            psmt1.setDouble(1,money);
            psmt1.setString(2,outUser) ;

            // 第五：执行 SQL 语句 - executeUpdate()、executeQuery()
            // 语法一：int 变量 = 语句对象.executeUpdate()
            // 语法二：ResultSet 变量 = 语句对象.executeQuery()
            psmt1.executeUpdate();
            System.out.println("转出成功");
            r = r + 1 ;
            // 第六：对结果进行处理 - 把结果集中的数据读取出来，并存储到实体对象中
            // 结果集对象.next() ： 判断是否存在下一条数据
            // 语法一：结果集对象.getXxx(查询字段的下标索引) : 获取某个字段的数据
            // 语法二：结果集对象.getXxx(查询字段的名称) : 获取某个字段的数据
        } catch (SQLException e) {
            System.out.println("转出失败");
            // 回滚事务
            try {
                conn.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally {
            // 第七：关闭对象
            DbUtil.close(null,psmt1,null);
        }

        // ------------ 转入操作 ----------------
        try {
            // 第三：预编译 SQL 语句 - 获取语句对象
            psmt2 = conn.prepareStatement(inSql);

            // 第四：给占位符填充数据 - 注：Xxx代表是数据类型
            // 语句对象.setXxx(参数索引,值)
            psmt2.setDouble(1,money);
            psmt2.setString(2,inUser) ;

            // 第五：执行 SQL 语句 - executeUpdate()、executeQuery()
            // 语法一：int 变量 = 语句对象.executeUpdate()
            // 语法二：ResultSet 变量 = 语句对象.executeQuery()
            psmt2.executeUpdate();
            System.out.println("转入成功");
            r = r + 1 ;
            // 第六：对结果进行处理 - 把结果集中的数据读取出来，并存储到实体对象中
            // 结果集对象.next() ： 判断是否存在下一条数据
            // 语法一：结果集对象.getXxx(查询字段的下标索引) : 获取某个字段的数据
            // 语法二：结果集对象.getXxx(查询字段的名称) : 获取某个字段的数据
        } catch (SQLException e) {
            System.out.println("转入失败");
            // 回滚事务
            try {
                conn.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally {
            // 第七：关闭对象
            DbUtil.close(null,psmt2,null);
        }

        if(r==2) {
            try {
                // 提交事务
                conn.commit();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                DbUtil.close(null,null,conn);
            }
        }

        return r ;
    }


    @Override
    public int updateMoney4Proc(String outUser, String inUser, double money) {
        int r = 0;

        // 第一：定义要操作数据库的 SQL 语句，参数使用 ? 占位符代替
        String sql = "{call proc_zhuang_zhang(?,?,?,?)}";

        // 第二：获取连接对象
        Connection conn = DbUtil.getConnection();
        CallableStatement cstmt = null ;

        // ------------ 转出操作 ----------------
        try {
            // 第三：预编译 SQL 语句 - 获取语句对象
            cstmt = conn.prepareCall(sql);

            // 第四：给占位符填充数据 - 注：Xxx代表是数据类型
            // 语句对象.setXxx(参数索引,值)
            cstmt.setString(1,outUser);
            cstmt.setString(2,inUser);
            cstmt.setDouble(3,money);

            // 注册输出参数的类型
            cstmt.registerOutParameter(4, Types.INTEGER);

            // 第五：执行 SQL 语句 - executeUpdate()、executeQuery()
            // 语法一：int 变量 = 语句对象.executeUpdate()
            // 语法二：ResultSet 变量 = 语句对象.executeQuery()
            cstmt.execute();

            // 第六：对结果进行处理 - 把结果集中的数据读取出来，并存储到实体对象中
            // 结果集对象.next() ： 判断是否存在下一条数据
            // 语法一：结果集对象.getXxx(查询字段的下标索引) : 获取某个字段的数据
            // 语法二：结果集对象.getXxx(查询字段的名称) : 获取某个字段的数据
            // 语法三：CallableStatement对象.getXxx(输出参数索引) : 获取输出参数的值

            // 提取输出参数的值
            r = cstmt.getInt(4) ;

        } catch (SQLException e) {

        } finally {
            // 第七：关闭对象
            DbUtil.close(null,cstmt,conn);
        }

        return r ;
    }
}
